Ciencia de Datos para Economistas

Clase 22- Uso de API’s

Autor/a
Afiliación

MSc. José M. Avendaño

Universidad Central de Venezuela- Escuela de Economía. 2024-2025

Fecha de publicación

29 de enero de 2025

Objetivo

Realizar consultas a distintas API’s y procesar los datos obtenidos.

Ciclo

Definición API´s

Las APIs (Application Programming Interfaces) son conjuntos de reglas y protocolos que permiten a diferentes aplicaciones comunicarse entre sí. En términos simples, una API es un intermediario que permite que dos programas se comuniquen sin necesidad de entender cómo están construidos internamente = vamos a ponernos de acuerdo

API REST (Representational State Transfer)

Es un estilo adoptado para diseñar servicios web, el cual se sustenta en el protocolo HTTP. Su objetivo principal es proporcionar una interfaz sencilla y eficiente para la comunicación entre diferentes sistemas o aplicaciones, permitiendo que puedan intercambiar datos de manera estándar.

¿Cómo Funcionan?

  1. Identificar la API : Encuentra una API que proporcione los datos que necesitas.

  2. Obtener credenciales (si es necesario) : Algunas APIs requieren claves de acceso o tokens para autenticar tus solicitudes.

  3. Realizar una solicitud HTTP : Utiliza métodos como GET, POST, etc., para enviar solicitudes a la API.

  4. Procesar la respuesta : La API devolverá los datos en un formato como JSON o XML, que se deben procesar.

Métodos

  • GET :

    • Se utiliza para solicitar datos del servidor.

    • Los parámetros se envían en la URL.

    • Es idempotente (realizar múltiples solicitudes tiene el mismo efecto que una sola).

    • No es seguro para enviar datos sensibles.

  • POST :

    • Se utiliza para enviar datos al servidor, como crear o actualizar recursos.

    • Los parámetros se envían en el cuerpo de la solicitud.

    • No es idempotente (cada solicitud puede tener un efecto diferente).

    • Es más seguro para enviar datos sensibles.

Ejemplos de API:

  1. Spotify:
    • Descripción: Proporciona acceso a bibliotecas de música, listas de reproducción, artistas y más.
  2. OpenWeatherMap:
    • Descripción: Ofrece datos meteorológicos en tiempo real, pronósticos y estadísticas históricas.
  3. Google Maps:
    • Descripción: Proporciona información geográfica, rutas, lugares de interés y más.
  4. GitHub:
    • Descripción: Permite acceder a repositorios, issues, pull requests y otros datos relacionados con el código fuente.
  5. Yelp:
    • Descripción: Ofrece información sobre negocios locales, reseñas, calificaciones y más.

JSON

JSON (JavaScript Object Notation) es un formato ligero de intercambio de datos que es fácil para humanos leer y escribir, y fácil para las computadoras de generar y analizar. Los datos generalmente están en estructuras anidadas

JSON 1: datos tabulares

  "empleados": [
    {
      "nombre": "Juan",
      "edad": 30,
      "departamento": {
        "nombre": "Ventas",
        "ubicacion": "Edificio A"
      }
    },
    {
      "nombre": "Ana",
      "edad": 25,
      "departamento": {
        "nombre": "Marketing",
        "ubicacion": "Edificio B"
      }
    }
  ]
}
library(jsonlite)
fromJSON('{
  "empleados": [
    {
      "nombre": "Juan",
      "edad": 30,
      "departamento": {
        "nombre": "Ventas",
        "ubicacion": "Edificio A"
      }
    },
    {
      "nombre": "Ana",
      "edad": 25,
      "departamento": {
        "nombre": "Marketing",
        "ubicacion": "Edificio B"
      }
    }
  ]
}')
$empleados
  nombre edad departamento.nombre departamento.ubicacion
1   Juan   30              Ventas             Edificio A
2    Ana   25           Marketing             Edificio B

JSON 2: datos no tabulares

  "libro": {
    "titulo": "1984",
    "autor": "George Orwell",
    "publicado": 1949,
    "generos": ["Dystopian", "Political Fiction"],
    "reseña": {
      "puntuacion": 4.5,
      "comentario": "Una visión profunda de un futuro distópico."
    }
  }
}
fromJSON('{
  "libro": {
    "titulo": "1984",
    "autor": "George Orwell",
    "publicado": 1949,
    "generos": ["Dystopian", "Political Fiction"],
    "reseña": {
      "puntuacion": 4.5,
      "comentario": "Una visión profunda de un futuro distópico."
    }
  }
}')
$libro
$libro$titulo
[1] "1984"

$libro$autor
[1] "George Orwell"

$libro$publicado
[1] 1949

$libro$generos
[1] "Dystopian"         "Political Fiction"

$libro$reseña
$libro$reseña$puntuacion
[1] 4.5

$libro$reseña$comentario
[1] "Una visión profunda de un futuro distópico."

Paquete HTTR2

Es un cliente HTTP completo que proporciona una API moderna y canalizable para trabajar con APIs web. Se basa en {curl} para proporcionar características como objetos de solicitud explícitos, herramientas integradas de limitación de velocidad y reintento, soporte completo de OAuth y manejo seguro de secretos y credenciales.

HTTR2 permite los métodos de solicitudes GET, POST, PUT, DELETE 

Si la descarga arroja un error de timeout es necesario ejecutar en consola options(timeout=numeroensegundos)

Inspección JSON

Usar función View

Caso 1: Patria Datos Covid Venezuela

Cifras COVID Venezuela disponibles en https://covid19.patria.org.ve/estadisticas-venezuela/

Url api: https://covid19.patria.org.ve/api-covid-19-venezuela/

Caso 1: request

library(httr2)
library(jsonlite)
library(dplyr)
req_patria <- request("https://covid19.patria.org.ve/api/v1/timeline")

req_patria

Caso 1: definición método

GET

req_patria |> 
  req_method("GET")

revisión consulta

req_patria |> 
  req_dry_run()
GET /api/v1/timeline HTTP/1.1
Host: covid19.patria.org.ve
User-Agent: httr2/1.0.7 r-curl/6.1.0 libcurl/8.7.1
Accept: */*
Accept-Encoding: gzip

Caso 1: realizar request

respuesta_patria <- req_perform(req_patria)

# posterior a consulta
respuesta_patria |> 
  resp_status_desc()
[1] "OK"
respuesta_patria |> 
  resp_content_type()
[1] "application/json"
#str(respuesta_patria) más info

Caso 1: procesar datos del request

datos_patria <- respuesta_patria$body%>%
  rawToChar()%>%
  fromJSON()

class(datos_patria)  
[1] "data.frame"
str(datos_patria)
'data.frame':   1146 obs. of  6 variables:
 $ Date     : chr  "2020-03-13" "2020-03-14" "2020-03-15" "2020-03-16" ...
 $ DateTS   : int  1584072000 1584158400 1584244800 1584331200 1584417600 1584504000 1584590400 1584676800 1584763200 1584849600 ...
 $ Confirmed:'data.frame':  1146 obs. of  2 variables:
  ..$ Count: int  2 10 17 33 36 41 43 70 73 77 ...
  ..$ New  : int  2 8 7 16 3 5 2 27 3 4 ...
 $ Recovered:'data.frame':  1146 obs. of  2 variables:
  ..$ Count: int  0 0 0 0 0 0 0 0 15 15 ...
  ..$ New  : int  0 0 0 0 0 0 0 0 15 0 ...
 $ Deaths   :'data.frame':  1146 obs. of  2 variables:
  ..$ Count: int  0 0 0 0 0 0 0 0 0 0 ...
  ..$ New  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ Active   :'data.frame':  1146 obs. of  1 variable:
  ..$ Count: int  2 10 17 33 36 41 43 70 58 62 ...

Caso 1: View de datos

Caso 1: limpieza de datos

desanidado y convertir fechas

df_datos_patria <- datos_patria%>%
  mutate(fecha=as.Date(Date))%>%
  mutate(Activos=as.integer(Active$Count))%>%
  mutate(conf_acu=as.integer(Confirmed$Count))%>%
  mutate(conf_nvos=as.integer(Confirmed$New))%>%
  mutate(recu_acu=as.integer(Recovered$Count))%>%
  mutate(recu_nvos=as.integer(Recovered$New))%>%
  mutate(falle_acu=as.integer(Deaths$Count))%>%
  mutate(falle_nvos=as.integer(Deaths$New))%>%
  select(-c(Confirmed, Recovered, Deaths, Active, Date, DateTS))

Caso 1: representación gráfica

uso de librería plotly

library(plotly)
plot_ly(df_datos_patria,
                        x = ~fecha, 
                        y = ~Activos,
                        type = 'bar',
                        name = 'COVID: Casos Activos Venezuela')

más info de plotly en el enlace

Caso 2: Buscador Empleo

Caso 2: Realizar Consulta

Se añaden headers que pide la API para entregar resultados

url_emplea <- 'https://www.empleate.com/venezuela/ofertas/empleos_encontrados/1/trabaios-en-venezuela-busqueda-por-economista'

req_emplea <- request(url_emplea)|>
  req_method("GET")|> 
  req_headers( Accept= "*/*",
               `Accept-Language`= "es,es-ES;q=0.9,en-US;q=0.8,en;q=0.7,gl;q=0.6",
               `User-Agent`= "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36")|>
  req_perform()

req_emplea

Caso 3: inspección respuesta

req_emplea|> 
  resp_content_type()
[1] "text/html"
datos_html <- req_emplea$body|>
  rawToChar()

substr(datos_html,201000,201600)
[1] "d+t+f2P9bwtRbfYvCvUkfJTAi/RmFVpUcGzZN/Tomnmf7HCfnQNn7t8+tZ0p9Azh5SF9wLVzO/xJOFFbDc7xnLTzEHES4C5tnVsKCkkpzPGqehOr/izfpvuB8H7rzazD8E8JvDOhlzSPeNgxK4HgCF6Z2XpSqnxbd3ivotJ9fskcOtcn7cJvYU8Tnx1Rx6qMQCzXxTal5I6YfB+w4jxhXGxfPmcPeLMZz/DB4jhx+2lTCSRSqjfoylmSKTvuvkuPuTP8flvQdMeb6WtKIUFYm++zJeM4mIUFjiASPorPhLmydifgO2PeH5pZcq1zJ1IcBr1+hvbgXOB5442HAg/0FDOAS4A6HaDyLh4HujJI7fiWshiv/zn+6pUW39zGU2oPh5EDq6wCuernXa8liivD8z1g0P8fmdm8Fra6TwHMytO4AnfZvsrktaPO0Gp1ydIsA3LAt7f53bDr439kxd2bJHEed0Cj3jlrB6lC2f+2bBJvOLVVhKTXXeLWr2en9dNpPYmFxGngLsLdWWUxC5fkshrZ8Tbwwi1rqQvcRN4aSj7K0dBKd9ovZuoHoeO22dWYfnfZdMfyF4xhSS4dIJNkDvjaN"
rvest::read_html(datos_html)
{html_document}
<html lang="es">
[1] <head>\n<!-- Meta --><title>Empléate | Venezuela, Colombia, México, Perú, España, E ...
[2] <body>\r\n<header><!--=== Header y nav ===--><link rel="stylesheet" href="/css/nav- ...

Caso 3 Dolar Monitor

Extraer datos de API de monitor dólar

Caso 3: realizar request

Esta petición necesita llevar headers

req_MonDol <- request('https://api.monitordolarvenezuela.com/historico')|>
  req_method("GET")|> 
  req_headers(Origin= "https://monitordolarvenezuela.com",
              Referer= "https://monitordolarvenezuela.com/") |>
  req_perform()

req_MonDol

Caso 3: analizar respuesta

  1. tipo de contenido:

    req_MonDol|> 
      resp_content_type()
    [1] "application/json"
  2. Extraer datos de respuesta y extraer del json

    datos_MonDol <- req_MonDol$body|>
      rawToChar()|>
      fromJSON()
  3. Consultar clase y nombres de la respuesta

    class(datos_MonDol)
    [1] "list"
    names(datos_MonDol)
    [1] "status" "total"  "result"
    # str(datos_MonDol) para más info

Caso 3: extraer df con datos

Es necesario hacer limpieza en las fechas, en los valores de caracteres a numéricos, redondear

df_MonDol <- datos_MonDol$result|>
  as_tibble()|>
  mutate(fecha= as.Date(fecha,format='%d/%m/%Y')) |>
  arrange(fecha) %>%
  mutate(across(all_of(c('MdvMin','MdvMax',
                         'BcvMin','BcvMax')), 
                as.numeric),
         across(all_of(c('MdvMin','MdvMax',
                         'BcvMin','BcvMax')), ~round(.x, 2)))

head(df_MonDol)
# A tibble: 6 × 6
  fecha      hora  MdvMin MdvMax BcvMin BcvMax
  <date>     <chr>  <dbl>  <dbl>  <dbl>  <dbl>
1 2024-12-31 00:00   65.2   65.9   52.0   52.0
2 2025-01-01 00:00   65.2   66.2   52.0   52.0
3 2025-01-02 00:00   64.8   66.1   52.0   52.6
4 2025-01-03 00:00   64.8   66.7   52.6   53.0
5 2025-01-04 00:00   66.0   66.6   53.0   53.0
6 2025-01-05 00:00   65.7   66.5   53.0   53.0

Caso 3: representación gráfica

library(apexcharter)
apex(data = df_MonDol, 
     mapping = aes(x = fecha, 
                   ymin = MdvMin,
                   ymax= MdvMax),
     type = "rangeArea",
     serie_name = '$ Monitor',
     synchronize = "df_MonDol")|>
  ax_colors(c( "#ff595e"))

apex(data = df_MonDol, 
     mapping = aes(x = fecha, 
                   ymin = BcvMin,
                   ymax= MdvMax),
     type = "rangeArea",
     serie_name = '$ BCV',
     synchronize = "df_MonDol") |>
  ax_colors( '#1982c4')

Caso 4: Consulta LLM 1, API Google AI Studio

Caso 4: obtener datos

library(rvest)
dato_texto_ucab <- read_html('https://economia.ucab.edu.ve/perspectivas-economicas-de-2025-discutieron-especialistas-en-la-ucab/')|>
  html_nodes('p')|>
  html_text()|>
  paste(collapse = '. ')%>%
  str_squish()

# inspección texto descargado
substr(dato_texto_ucab, 100, 1400)  
[1] "diantes Economía | 0 Comentarios. . En un congreso organizado por la Escuela de Economía, los panelistas señalaron que la brecha entre el tipo de cambio oficial y el paralelo suele preceder procesos de devaluación, como ya lo está experimentando el bolívar. Dijeron que el próximo año seguirá marcado por los esfuerzos que se hagan para incrementar la producción petrolera, mientras que el mercado bursátil intentará convertirse en un actor protagónico en el ámbito del financiamiento. Las condiciones estructurales de la economía venezolana hacia el cierre de 2024 invitan a pensar que en 2025 el país experimentará una mayor inflación que la vista este año, según proyectaron expertos durante el foro ‘»Perspectivas Económicas: Retos y Oportunidades para la Economía Venezolana», realizado en el marco del XXVIII Congreso de Actualidad Económica de la Escuela de Economía de la UCAB.. En las últimas semanas, el bolívar ha venido sufriendo una caída importante de su valor frente al dólar, rompiendo con la relativa estabilidad monetaria que caracterizó la mayor parte del año. El tipo de cambio oficial, determinado por el Banco Central de Venezuela (BCV) se desplazó 15,86% en apenas un mes, al pasar de Bs 38,88 a Bs 45,05. A esto se suma la brecha que se mantiene con el tipo de cambio paralelo,"

Caso 4: definir prompt consulta

Eres un experto en análisis de noticias económicas. Vas a extraer en formato json las ideas principales expuestas en el texto {idea_principal_nombre: descripcion} del texto delimitado por triple asterisco. Texto: *** ……. ***. Recuerda solo extraer el valor y no añadir información adicional.

# definir el prompt
prompt <- 'Eres un experto en análisis de noticias económicas. Vas a extraer en formato json las ideas principales expuestas en el texto {idea_principal_nombre: descripcion} del texto delimitado por triple asterisco. Texto: ***'

post_texto <- '***.  Recuerda solo extraer el valor y no añadir información adicional. '

dato_texto_prompt_gooaistudio <- paste(prompt,
                                       dato_texto_ucab,
                                       post_texto)

Caso 4: API Google AI Studio

Conectarse desde R a esta API que pide KEY y body en el request

Caso 4: crear request

Cambiar API key

gooai_studio_url <- 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent'
                
api_key <- ''

llm_resultado_google <- request(gooai_studio_url) %>%
  req_headers("Content-Type" = "application/json") %>%
  req_body_json(
    list(
      contents = list(
        list(
          parts = list(
            list(text = dato_texto_prompt_gooaistudio)
          )
        )
      )
    )
  ) %>% 
  req_url_query(key = api_key) %>% 
  req_method("POST")|>
  req_perform()

Caso 4: procesar datos request

library(stringr)

datos_goo_respuesta <- llm_resultado_google$body |>
  rawToChar() |>
  fromJSON()%>%
  .$candidates %>%
  .$content%>%
  .$parts%>%
  .[[1]]%>%
  str_squish(.)%>%
  str_remove_all(.,'```json | ```')%>%
  fromJSON()

Caso 4: Analizar resultados

#|eval: true
#|echo: false


datos_goo_respuesta
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        parts
1 ```json\n{\n  "Inflación y tipo de cambio": "La brecha entre el tipo de cambio oficial y el paralelo en Venezuela anticipa procesos de devaluación y aumento de la inflación. Se proyecta una inflación del 50% para 2024 y del 70% para 2025, aunque se descarta una hiperinflación inminente. La política de anclaje del tipo de cambio oficial, mediante la inyección de dólares, muestra fisuras y su efectividad depende del déficit fiscal.",\n  "Producción petrolera": "Para 2025 se espera un incremento en la producción petrolera, superando posiblemente el millón de barriles diarios gracias a las inversiones de Chevron. Sin embargo, la dependencia del petróleo y las sanciones limitan el crecimiento económico.",\n  "Mercado bursátil": "El mercado bursátil venezolano busca un rol protagónico en el financiamiento, con la Bolsa de Valores de Caracas duplicando sus cifras en 2024.  Se requiere promover la educación financiera y la imagen de Venezuela como destino de inversión para atraer capital extranjero.",\n  "Resiliencia económica": "La economía venezolana se presenta como un posible espacio de consenso y diálogo en un contexto político polarizado. Se destaca la necesidad de abandonar el modelo rentista y extractivista para lograr un desarrollo sostenible."\n}\n```\n
   role
1 model

Caso 5: Consulta LLM 2, Ollama local network

Caso 5: obtener datos

library(rvest)
library(stringr)
dato_texto <- read_html('https://www.swissinfo.ch/spa/el-precio-del-dólar-en-venezuela-supera-los-57-bolívares-y-la-moneda-local-sigue-en-caída/88794237')|>
  html_nodes('p')|>
  html_text()|>
  paste(collapse = '. ')%>%
  str_squish()
substr(dato_texto, 200, 400)  
[1] " de tres meses frente a la estadounidense, usada ampliamente en el país caribeño para cotizar bienes y algunos servicios.. Según informó el Banco Central de Venezuela (BCV), el dólar alcanzó hoy los 57"

Caso 5: crear prompt

Prompt: vas a extraer en formato json el valor del dolar del texto delimitado por triple asterisco. Texto: *** …. ***. Recuerda solo extraer el valor y no añadir información adicional.

prompt <- 'vas a extraer en formato json el valor del dolar del texto delimitado por triple asterisco. Texto: ***'
  
post_texto <- '***.  Recuerda solo extraer el valor y no añadir información adicional. '

dato_texto_prompt <- paste(prompt,
                           dato_texto,
                           post_texto)

Caso 5: crear request

  • Cambiar url por el de la IP donde está la API en la red local

  • Se pasan distintos argumentos en el body del request: modelo, prompt, temperatura del llm, etc

url_ollama <- 'http://localhost:11434' # modificar url por dirección ip host

endpoint <- paste0(url_ollama, '/api/generate')

llm_resultado <- request(endpoint)|>
  req_method("POST")|> 
  req_body_json(list(  model='llama3.2:1b',
                       prompt = dato_texto_prompt,
                       raw=FALSE,
                       format = "json",
                       options=list(
                         temperature= 0.1),
                       stream = FALSE,
                       keep_alive='3m'))|>
  req_perform()|>
  resp_body_json()

Caso 5: procesar request

Los datos hay que extraerlos del JSON

fromJSON(llm_resultado$response)|>
  as_tibble()
# A tibble: 1 × 1
  dolar
  <dbl>
1  57.3

Caso 6: Consulta API Cepal

https://statistics.cepal.org/portal/cepalstat/open-data.html?lang=es

Obtener Clasificador Temático

datos_cepal <- request("https://api-cepalstat.cepal.org/cepalstat/api/v1/thematic-tree?lang=es&format=json")|>
  req_headers("Accept" = "application/json")|>
  req_perform()|>
  resp_body_json()